﻿using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
//using UnityEngine.Experimental.UIElements;

namespace XFFSM
{
    public class BackgroundLayer : GraphLayer
    {

        #region 常量

        const int Cell_Size_Min = 30;
        const int Cell_Size_Max = 300;

        #endregion

        #region 字段
        private Vector2 mousePosition;
        #endregion

        #region 方法


        public BackgroundLayer(FSMEditorWindow editorWindow) : base(editorWindow) { }

        public override void OnGUI(Rect rect)
        {
            base.OnGUI(rect);

            EditorGUI.DrawRect(rect, ColorConst.BackgroundColor);
            if (Event.current.type == EventType.Repaint)
            {

                DrawGrid(Cell_Size_Min, ColorConst.GridColor, rect);
                DrawGrid(Cell_Size_Max, ColorConst.GridColor, rect);
            }
        }

        public override void ProcessEvents()
        {
            base.ProcessEvents();

            // 监听鼠标中键拖拽
            if ( Event.current.type == EventType.MouseDrag && Event.current.button == 2 && position.Contains(Event.current.mousePosition)) {
                this.Context.DragOffset += Event.current.delta;
                Event.current.Use();
            }

            // 监听鼠标滚轮滚动的事件
            if (Event.current.type == EventType.ScrollWheel && position.Contains(Event.current.mousePosition)) {
                this.Context.ZoomFactor -= Mathf.Sign( Event.current.delta.y) / 20.0f;
                this.Context.ZoomFactor = Mathf.Clamp(this.Context.ZoomFactor, 0.2f, 1);

                Event.current.Use();
            }

            // 鼠标按下
            if (Event.current.type == EventType.MouseDown && Event.current.button == 0) {
                this.Context.ClearSelections();
                this.Context.StopPreviewTransition();
                Event.current.Use();
            }

            if ( Event.current.type == EventType.MouseUp && Event.current.button == 1 
                &&this.Context.RuntimeFSMController != null 
                && !Application.isPlaying
                ) {

                // 停止预览
                this.Context.StopPreviewTransition();

                mousePosition = Event.current.mousePosition;
                // 显示菜单选项
                ShowMenu();
                Event.current.Use();
            }

        }

        // 在某一个区域绘制网格
        private void DrawGrid(float gridSpacing, Color gridColor, Rect rect) {

            if (gridSpacing == 0) { return; }

            if (Mathf.Abs(gridSpacing) > rect.width || Mathf.Abs(gridSpacing) > rect.height)  return;

            gridSpacing *= this.Context.ZoomFactor;

            DrawHorLine(rect, gridColor, gridSpacing);
            DrawHorLine(rect, gridColor, -gridSpacing, 1);

            DrawVerLine(rect, gridColor, gridSpacing);
            DrawVerLine(rect, gridColor, -gridSpacing, 1);
        }

        // 在某一个区域绘制竖线
        private void DrawVerLine(Rect rect, Color gridColor, float gridSpacing, int startIndex = 0) {
            Vector2 center = rect.center + this.Context.DragOffset;
            Vector2 start;
            Vector2 end;
            int i = startIndex;

            if ( center.x < rect.x && gridSpacing > 0 ) {
                i = (int)((rect.x - center.x) / gridSpacing);
                if ( rect.x  - center.x >= gridSpacing * i ) {
                    i++;
                }
            }

            if (center.x > (rect.x + rect.width) && gridSpacing < 0) {
                i =(int)((center.x - (rect.x + rect.width)) / Mathf.Abs(gridSpacing));
                if (center.x - (rect.x + rect.width) >= Mathf.Abs(gridSpacing) * i) {
                    i++;
                }
            }

            do
            {
                start = new Vector2(center.x + gridSpacing * i,rect.center.y - rect.height / 2);
                end = new Vector2(center.x + gridSpacing * i, rect.center.y + rect.height / 2);
                if (rect.Contains((start + end) / 2))
                {
                    DrawLine(start, end, gridColor);
                }
                i++;
            } while (rect.Contains((start + end) / 2));
        }

        // 在某一个区域绘制横线
        private void DrawHorLine(Rect rect,Color gridColor,float gridSpacing,int startIndex = 0) {

            Vector2 center = rect.center + this.Context.DragOffset;
            Vector2 start;
            Vector2 end;
            int i = startIndex;

            if ( center.y < rect.y && gridSpacing > 0 ) {
                i = (int)((rect.y - center.y) / gridSpacing);
                if ( rect.y - center.y >= i * gridSpacing ) {
                    i++;
                }
            }

            if ( center.y > (rect.y + rect.height) && gridSpacing < 0 ) {
                i = (int)((center.y - (rect.y + rect.height)) / Mathf.Abs(gridSpacing));
                if (center.y - (rect.y + rect.height) >= i *   Mathf.Abs(gridSpacing)) {
                    i++;
                }
            }

            do
            {
                start = new Vector2(rect.center.x - rect.width / 2 ,center.y + gridSpacing * i );
                end = new Vector2(rect.center.x + rect.width / 2, center.y + gridSpacing * i);
                if (rect.Contains((start + end) / 2)) { 
                    DrawLine(start, end, gridColor);
                }
                
                i++;
            } while (rect.Contains( (start + end) / 2 ));

        }

        // 画线段
        private void DrawLine(Vector2 start,Vector2 end,Color lineColor) {
            GL.Begin(GL.LINES);
            GL.Color(lineColor);

            GL.Vertex(start);
            GL.Vertex(end);


            GL.End();
        }

        private void ShowMenu() {
            this.Context.SelectNodes.Clear();

            var genericMenu = new GenericMenu();
            genericMenu.AddItem(new GUIContent("Create State"), false, () => {
                // TODO
                CreateState();
            });
            genericMenu.ShowAsContext();
        }

        private void CreateState() {

            Rect rect = new Rect(0, 0, FSMConst.StateNodeWith, FSMConst.StateNodeHeight);

            rect.center = GetNodePostion( mousePosition);

            FSMStateNodeFactory.CreateStateNode(this.Context.RuntimeFSMController, rect, this.Context.RuntimeFSMController.states.Count == 2);

        }

        private Vector2 GetNodePostion(Vector2 mousePosition) {

            Vector2 center = mousePosition + (mousePosition - this.position.center) * (1 - this.Context.ZoomFactor) / this.Context.ZoomFactor;

            center -= this.Context.DragOffset / this.Context.ZoomFactor;
            return center;
        }

        #endregion




    }

}

